package porter

import (
	"context"
	"github.com/nilorg/go-opentaobao/v2"
	"github.com/tidwall/gjson"
	"os"
	"shop/src/model"
	"time"
)

var taobaoClient = func() *opentaobao.Client {
	client := opentaobao.NewClient(
		opentaobao.WithAppKey(os.Getenv("APP_KEY")),
		opentaobao.WithAppSecret(os.Getenv("APP_SECRET")),
	)
	return client
}()

type tbTradeFetcher struct {
	store *model.Store
}

func (f *tbTradeFetcher) fetch(startTime time.Time, endTime time.Time, pageNo int, _ any, hasTotal bool) (any, error) {
	ctx := context.Background()
	ctx = opentaobao.NewSessionContext(ctx, f.store.AccessToken)
	resp, err := taobaoClient.Execute(ctx, "taobao.trades.sold.get", opentaobao.Parameter{
		"start_created": startTime,
		"end_created":   endTime,
		"page_no":       pageNo,
		"page_size":     f.pageSize(),
		"use_has_next":  !hasTotal,
	})

	if err != nil {
		return nil, err
	}
	return resp.Get("trades_sold_get_response"), nil
}

func (f *tbTradeFetcher) hasTotal() bool {
	return false
}

func (f *tbTradeFetcher) count(resp interface{}) int {
	r := resp.(gjson.Result)
	i := r.Get("total_results").Int()
	return int(i)
}

func (f *tbTradeFetcher) buildDocument(resp any) []model.Document {
	r := resp.(gjson.Result)
	trades := r.Get("trades.trade").Array()
	var doc model.Document
	now := time.Now()
	docs := make([]model.Document, len(trades))
	for _, t := range trades {
		doc.Sn = t.Get("tid").String()
		doc.CreatedTime = now
		doc.UpdatedTime = now
		doc.Doc = t.Str
		docs = append(docs, doc)
	}
	return docs
}

func (f *tbTradeFetcher) parameters() []any {
	return nil
}

func (f *tbTradeFetcher) pageSize() int {
	return 100
}

func (f *tbTradeFetcher) startPage() int {
	return 1
}

type tbRefundFetcher struct {
	store *model.Store
}

func (f *tbRefundFetcher) fetch(_ time.Time, _ time.Time, pageNo int, _ any, _ bool) (any, error) {
	ctx := context.Background()
	ctx = opentaobao.NewSessionContext(ctx, f.store.AccessToken)
	resp, err := taobaoClient.Execute(ctx, "taobao.refunds.apply.get", opentaobao.Parameter{
		"page_no":   pageNo,
		"page_size": f.pageSize(),
	})

	if err != nil {
		return nil, err
	}
	return resp.Get("refunds_apply_get_response"), nil
}

func (f *tbRefundFetcher) hasTotal() bool {
	return false
}

func (f *tbRefundFetcher) count(resp interface{}) int {
	r := resp.(gjson.Result)
	i := r.Get("total_results").Int()
	return int(i)
}

func (f *tbRefundFetcher) buildDocument(resp any) []model.Document {
	r := resp.(gjson.Result)
	trades := r.Get("refunds.refund").Array()
	var doc model.Document
	now := time.Now()
	docs := make([]model.Document, len(trades))
	for _, t := range trades {
		doc.Sn = t.Get("tid").String()
		doc.Rsn = t.Get("refund_id").String()
		doc.CreatedTime = now
		doc.UpdatedTime = now
		doc.Doc = t.Str
		docs = append(docs, doc)
	}
	return docs
}

func (f *tbRefundFetcher) parameters() []any {
	return nil
}

func (f *tbRefundFetcher) pageSize() int {
	return 100
}

func (f *tbRefundFetcher) startPage() int {
	return 1
}
